home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
complxo.exe
/
COMPLEXO.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-01-15
|
23KB
|
729 lines
{$N+,E+} {Use math coprocessor, if any, emulate otherwise.}
UNIT ComplexOps;
{This UNIT provides complex arithmetic and transcendental functions.
(C) Copyright 1990, 1992, Earl F. Glynn, Overland Park, KS. Compuserve 73257,3527.
All rights reserved. This program may be freely distributed only for
non-commercial use.
Some ideas in this UNIT were borrowed from "A Pascal Tool for Complex
Numbers", Journal of Pascal, Ada, & Modula-2, May/June 1985, pp. 23-29.
Many complex formulas were taken from Chapter 4, "Handbook of Mathematical
Functions" (Ninth Printing), Abramowitz and Stegun (editors), Dover, 1972.}
INTERFACE
TYPE
RealType = DOUBLE;
ComplexForm = (polar,rectangular);
Complex =
RECORD
CASE form: ComplexForm OF
rectangular: (x,y : RealType); {z = x + y*i}
polar : (r,theta: RealType); {z = r*CIS(theta)}
END; {where CIS(theta) = COS(theta) + SIN(theta)*i}
{ theta = -PI..PI (in canonical form)}
CONST
MaxTerm : BYTE = 35;
EpsilonSqr : RealType = 1.0E-20;
Infinity : RealType = 1.0E25; {virtual infinity}
{complex number definition/conversion/output}
PROCEDURE CConvert (VAR z: Complex; f: ComplexForm);
PROCEDURE CSet (VAR z: Complex; a,b: RealType; f: ComplexForm);
FUNCTION CStr (z: Complex; w,d: BYTE; f: ComplexForm): STRING;
{complex arithmetic}
PROCEDURE CAdd (VAR z: Complex; a,b: Complex); {z = a + b}
PROCEDURE CDiv (VAR z: Complex; a,b: Complex); {z = a / b}
PROCEDURE CMult (VAR z: Complex; a,b: Complex); {z = a * b}
PROCEDURE CSub (VAR z: Complex; a,b: Complex); {z = a - b}
PROCEDURE CNeg (VAR z: Complex; a : Complex); {z = -a }
{complex natural log, exponential}
PROCEDURE CLn (VAR fn : Complex; z: Complex); {fn = ln(z) }
PROCEDURE CExp (VAR z : Complex; a: Complex); {z = exp(a)}
PROCEDURE CPwr (VAR z : Complex; a,b: Complex); {z = a^b }
{complex trig functions}
PROCEDURE CCos (VAR z: Complex; a: Complex); {z = cos(a)}
PROCEDURE CSin (VAR z: Complex; a: Complex); {z = sin(a)}
PROCEDURE CTan (VAR z: Complex; a: Complex); {z = tan(a)}
PROCEDURE CSec (VAR z: Complex; a: Complex); {z = sec(a)}
PROCEDURE CCsc (VAR z: Complex; a: Complex); {z = csc(a)}
PROCEDURE CCot (VAR z: Complex; a: Complex); {z = cot(a)}
{complex hyperbolic functions}
PROCEDURE CCosh (VAR z: Complex; a: Complex); {z = cosh(a)}
PROCEDURE CSinh (VAR z: Complex; a: Complex); {z = sinh(a)}
PROCEDURE CTanh (VAR z: Complex; a: Complex); {z = tanh(a)}
PROCEDURE CSech (VAR z: Complex; a: Complex); {z = sech(a)}
PROCEDURE CCsch (VAR z: Complex; a: Complex); {z = csch(a)}
PROCEDURE CCoth (VAR z: Complex; a: Complex); {z = coth(a)}
{miscellaneous complex functions}
FUNCTION CAbs (z: Complex): RealType; {CAbs = |z|}
FUNCTION CAbsSqr (z: Complex): RealType; {CAbsSqr = |z|^2}
PROCEDURE CIntPwr (VAR z: Complex; a: Complex; n: INTEGER); {z = a^n}
PROCEDURE CRealPwr (VAR z: Complex; a: Complex; x: RealType); {z = a^x}
PROCEDURE CConjugate (VAR z: Complex; a: Complex); {z = a*}
PROCEDURE CSqrt (VAR z: Complex; a: Complex); {z = SQRT(a)}
PROCEDURE CRoot (VAR z: Complex; a: Complex; k,n: WORD); {z = a^(1/n)}
{complex Bessel functions of order zero}
PROCEDURE CI0 (VAR sum: Complex; z: Complex); {sum = I0(z)}
PROCEDURE CJ0 (VAR sum: Complex; z: Complex); {sum = J0(z)}
PROCEDURE CLnGamma (VAR z: Complex; a: Complex);
PROCEDURE CGamma (VAR z: Complex; a: Complex);
{treat "fuzz" of real numbers}
PROCEDURE CDeFuzz (VAR z: Complex);
FUNCTION DeFuzz (x: RealType): RealType;
PROCEDURE SetFuzz (value: RealType);
{miscellaneous}
FUNCTION FixAngle (theta: RealType): RealType; {-PI < theta <= PI}
FUNCTION Pwr (x,y: RealType): RealType; {Pwr = x^y}
FUNCTION Log10 (x: RealType): RealType;
FUNCTION LongMod (l1,l2: LongInt): LongInt;
FUNCTION Cosh (x: RealType): RealType;
FUNCTION Sinh (x: RealType): RealType;
IMPLEMENTATION
VAR
fuzz : RealType;
Cone : Complex;
Cinfinity: Complex;
Czero : Complex;
hLnPI : RealType;
hLn2PI : RealType;
ln2 : RealType;
{complex number definition/conversion/output}
PROCEDURE CConvert (VAR z: Complex; f: ComplexForm);
VAR a: Complex;
BEGIN
IF z.form = f
THEN CDeFuzz (z)
ELSE BEGIN
CASE z.form OF
polar: {polar-to-rectangular conversion}
BEGIN
a.form := rectangular;
a.x := z.r * COS(z.theta);
a.y := z.r * SIN(z.theta)
END;
rectangular: {rectangular-to-polar conversion}
BEGIN
a.form := polar;
IF DeFuzz(z.x) = 0.0
THEN BEGIN
IF DeFuzz(z.y) = 0.0
THEN BEGIN
a.r := 0.0;
a.theta := 0.0
END
ELSE
IF z.y > 0.0
THEN BEGIN
a.r := z.y;
a.theta := 0.5*PI
END
ELSE BEGIN
a.r := -z.y;
a.theta := -0.5*PI
END
END
ELSE BEGIN
a.r := CAbs(z);
a.theta := ARCTAN(z.y/z.x); {4th/1st quadrant -PI/2..PI/2}
IF z.x < 0.0 {2nd/3rd quadrants}
THEN
IF z.y >= 0.0
THEN a.theta := PI + a.theta {2nd quadrant: PI/2..PI}
ELSE a.theta := -PI + a.theta {3rd quadrant: -PI..-PI/2}
END
END;
END;
CDeFuzz (a);
z := a
END
END {CConvert};
PROCEDURE CSet (VAR z: Complex; a,b: RealType; f: ComplexForm);
BEGIN
z.form := f;
CASE f OF
polar:
BEGIN
z.r := a;
z.theta := b
END;
rectangular:
BEGIN
z.x := a;
z.y := b
END;
END
END {CSet};
FUNCTION CStr (z: Complex; w,d: BYTE; f: ComplexForm): STRING;
VAR s1,s2: STRING;
BEGIN
CConvert (z,f);
CASE f OF
polar:
BEGIN
Str (z.r:w:d, s1);
Str (z.theta:w:d, s2);
CStr := s1+'*CIS('+s2+')'
END;
rectangular:
BEGIN
Str (z.x:w:d, s1);
Str (ABS(z.y):w:d, s2);
IF z.y >= 0
THEN CStr := s1+' +'+s2+'i'
ELSE CStr := s1+' -'+s2+'i'
END
END
END {CStr};
{complex arithmetic}
PROCEDURE CAdd (VAR z: Complex; a,b: Complex); {z = a + b}
BEGIN {complex addition}
CConvert (a,rectangular);
CConvert (b,rectangular);
z.form := rectangular;
z.x := a.x + b.x; {real part}
z.y := a.y + b.y; {imaginary part}
END {CAdd};
PROCEDURE CDiv (VAR z: Complex; a,b: Complex); {z = a / b}
VAR temp: RealType;
BEGIN
CConvert (b,a.form); {arbitrarily convert one to type of other}
z.form := a.form;
CASE a.form OF
polar:
BEGIN
z.r := a.r / b.r;
z.theta := FixAngle(a.theta - b.theta)
END;
rectangular:
BEGIN
temp := SQR(b.x) + SQR(b.y);
z.x := (a.x*b.x + a.y*b.y) / temp;
z.y := (a.y*b.x - a.x*b.y) / temp
END
END
END {CDiv};
PROCEDURE CMult (